from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated
from courses.models import Course, CourseExpire
from rest_framework.response import Response
from django_redis import get_redis_connection
from rest_framework import status


# Create your views here.

class CartAPIView(ViewSet):
    # permission_classes = [IsAuthenticated]

    def add_cart(self, request):
        """添加商品到购物车"""
        # 接收客户端提交的数据， [用户ID，课程ID，有效期和勾选状态]
        user_id = request.user.id
        course_id = request.data.get("course_id")
        expire = 0  # 默认有效期。0表示没有勾选
        selected = True  # 默认是勾选状态

        # 校验数据
        try:
            Course.objects.get(is_show=True, is_delete=False, pk=course_id)
        except Course.DoesNotExist:
            return Response({"message": "当前商品不存在！", status: status.HTTP_400_BAD_REQUEST})

        # todo 判断用户是否已经购买，如果购买。有效期内不允许再次购买

        # 连接redis

        redis_conn = get_redis_connection("cart")

        # 保存数据
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hset("cart_%s" % user_id, course_id, expire)
        pipe.sadd("selected_%s" % user_id, course_id)
        pipe.execute()
        # 查询购物车的数量
        cart_length = redis_conn.hlen('cart_%s' % user_id)

        # 响应结果

        return Response({"message": "成功添加商品到购物车！", "cart_length": cart_length})

    def get_cart(self, request):
        """获取购物车数据"""
        # 获取用户id
        user_id = request.user.id

        # 根据用户到购物车中获取数据
        redis_conn = get_redis_connection("cart")
        cart_hash_bytes = redis_conn.hgetall("cart_%s" % user_id)
        selected_set = redis_conn.smembers("selected_%s" % user_id)

        # 根据购物车商品id 到mysql中获取商品具体信息
        data = []
        for course_id_bytes, expire_bytes in cart_hash_bytes.items():
            course_id = course_id_bytes.decode()
            expire = int(expire_bytes.decode())

            try:
                course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
            except Course.DoesNotExist:
                # 如果商品已经下架或者逻辑删除，则不会再显示到购物车中
                continue

            data.append({
                "course_id": course.id,
                "course_img": course.course_img.url,
                "course_name": course.name,
                'expire_list': course.expire_list,  # to do 后面实现了课程购买有效期以后返回有效期选项列表
                "expire_time": int(expire),
                # 'price': course.get_price_by_expire(expire),            # 获取价格
                'price': course.get_discount_pirce_by_expire(expire),  # 根据有效期获取价格
                "selected": course_id_bytes in selected_set  # 运算符，结果是true和false
            })

        # 返回结果
        return Response(data)

    def change_selected_status(self, request):
        """修改商品勾选状态"""
        # 获取客户端提交的数据
        user_id = request.user.id
        course_id = request.data.get('course_id')
        selected = request.data.get("selected")

        # 连接redis
        redis_conn = get_redis_connection('cart')

        # 切换勾选状态
        if selected:
            # 勾选
            redis_conn.sadd("selected_%s" % user_id, course_id)
        else:
            # 取消勾选
            redis_conn.srem("selected_%s" % user_id, course_id)

        # 返回结果
        return Response({"message": "切换勾选状态成功！"})

    def del_cart(self, request):
        """删除购物车中的商品"""
        user_id = request.user.id
        course_id = request.query_params.get('course_id')

        try:
            Course.objects.get(id=course_id)
        except Course.DoesNotExist:
            return Response({'message': "删除商品不存在！"})

        # 连接redis
        redis_conn = get_redis_connection("cart")

        # 根据用户id删除指定商品id的数据
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hdel("cart_%s" % user_id, course_id)
        pipe.srem("selected_%s" % user_id, course_id)
        pipe.execute()

        # 返回结果
        return Response({"message": "删除商品数据成功！"})

    def change_expire(self, request):
        """切换课程的有效期选项"""
        # 获取用户提交的数据【用户id。 课程id。选项】

        user_id = request.user.id
        course_id = request.data.get("course_id")
        expire_time = request.data.get('expire')

        # 校验数据
        try:
            Course.objects.get(pk=course_id, is_show=True, is_delete=False)
        except Course.DoesNotExist:
            return Response({"message": "课程不存在"}, status=status.HTTP_400_BAD_REQUEST)

        if expire_time > 0:
            try:
                CourseExpire.objects.get(course_id=course_id, expire=expire_time)
            except CourseExpire.DoesNotExist:
                return Response({"message": "课程有效期选项不存在"}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection("cart")

        redis_conn.hset("cart_%s" % user_id, course_id, expire_time)

        return Response({"message": "修改有效期选项成功"})

    def get_selected_course(self, request):
        """获取已勾选课程的购物车商品信息"""
        user = request.user
        # 根据用户id到购物车中查询商品信息
        redis_conn = get_redis_connection('cart')
        cart_hash = redis_conn.hgetall('cart_%s' % user.id)
        selected_set = redis_conn.smembers('selected_%s' % user.id)

        # 根据购物车中的商品id到mysql中提取商品具体信息
        data = []
        for course_id_bytes in selected_set:
            course_id = course_id_bytes.decode()
            expire = int(cart_hash[course_id_bytes].decode())

            try:
                course = Course.objects.get(pk=course_id, is_show=True, is_delete=False)
            except Course.DoesNotExist:
                # 如果当前商品被下架或者被逻辑删除，则不显示到购物车商品列表中
                continue

            try:
                ret = CourseExpire.objects.get(course_id=course_id, expire=expire)
                expire_text = ret.text
            except:
                expire_text = '永久有效'

            data.append({
                "course_id": course_id,
                "course_img": course.course_img.url,
                'course_name': course.name,
                'discount_name': course.discount_name,
                'expire_text': expire_text,
                'original_price': course.get_price_by_expire(expire),
                'discount_price': course.get_discount_pirce_by_expire(expire)
            })

        # 返回结果
        return Response(data)

